package org.bspv.pharma.dao;

import java.io.Serializable;
import java.util.List;

/**
 * Interface generique de manipulation d'objet persistant
 * 
 * @param <E>
 *            Le type d'objet persistant a manipuler
 * @param <ID>
 *            Le type d'ID utiliser par l'objet persistant
 */
public interface DAO<E, ID extends Serializable> {

	/**
	 * Sauvegarde un objet
	 * 
	 * @param e
	 *            L'objet a sauvegarder
	 * @return L'objet apres sauvegarde (id complete)
	 */
	ID save(E e);

	/**
	 * Supprime un objet
	 * 
	 * @param e
	 *            L'objet a supprimer
	 */
	void delete(E e);

	/**
	 * Recharge un objet
	 * 
	 * @param e
	 *            L'objet a recharger
	 * @return L'objet recharge
	 */
	E refresh(E e);

	/**
	 * Sauvegarde une collection d'objet
	 * 
	 * @param elements
	 *            La collection d'objet a sauvegarder
	 * @return La collection d'objet apres sauvegarde (ids completes)
	 */
	List<E> save(List<E> elements);

	/**
	 * Supprime une List d'objet
	 * 
	 * @param elements
	 *            L'objet a supprimer
	 */
	void delete(List<E> elements);

	/**
	 * Recharge une List d'objet
	 * 
	 * @param elements
	 *            La List d'objet a recharger
	 * @return La List d'objet rechargee
	 */
	List<E> refresh(List<E> elements);

	/**
	 * Charge un objet en fonction de son id
	 * 
	 * @param id
	 *            L'id de l'objet a charger
	 * @return L'objet souhaite ou null si non existant
	 */
	E findById(ID id);

	/**
	 * Charge des objets en fonction de la valeur d'un de leur attribut
	 * 
	 * @param attr
	 *            Le nom de l'attribut
	 * @param value
	 *            La valeur de l'attribut
	 * @return La List d'objet souhaite
	 */
	List<E> findBy(String attr, Object value);

	/**
	 * Charge des objets en fonction de la valeur d'un de leur attribut en les
	 * triant
	 * 
	 * @param attr
	 *            Le nom de l'attribut
	 * @param value
	 *            La valeur de l'attribut
	 * @param order
	 *            Le nom de l'attribut pour trier
	 * @param ascendant
	 *            La direction du tri
	 * @return La List d'objet souhaite
	 */
	List<E> findByOrdered(String attr, Object value, String order,
			boolean ascendant);

	/**
	 * Charge des objets a partir d'un objet exemple (LIKE active)
	 * 
	 * @param example
	 *            L'exemple
	 * @return La List d'objet souhaite
	 */
	List<E> findByExample(E example);

	/**
	 * Charge des objets a partir d'un objet exemple et d'une liste de
	 * proprietes e ignorer pour construire la requete
	 * 
	 * @param example
	 *            L'exemple
	 * @return La List d'objet souhaite
	 */
	public List<E> findByExample(E example, List<String> propertiesToIgnore,
			boolean enableLike);

	/**
	 * Charge des objets en fonction de la valeur d'un ensemble de leurs
	 * attributs
	 * 
	 * @param attr
	 *            Le nom de l'attribut
	 * @param value
	 *            La valeur de l'attribut
	 * @return La List d'objet souhaite
	 */
	List<E> findBy(String[] attr, Object[] value);

	/**
	 * Charge des objets en fonction de la valeur d'un ensemble de leurs
	 * attributs en les triant
	 * 
	 * @param attr
	 *            Le nom de l'attribut
	 * @param value
	 *            La valeur de l'attribut
	 * @param order
	 *            Le nom de l'attribut pour trier
	 * @param ascendant
	 *            La direction du tri
	 * @return La List d'objet souhaite
	 */
	List<E> findByOrdered(String[] attr, Object[] value, String order,
			boolean ascendant);

	/**
	 * Charge tous les objets manages par ce DAO
	 * 
	 * @return La List d'objet
	 */
	List<E> findAll();

	/**
	 * Charge des objets en fonction de la valeur d'un ensemble de leurs
	 * attributs et des proprietes nulles ou non nulles
	 * 
	 * @param attr
	 * @param value
	 * @param nullProperties
	 * @param notNullProperties
	 * @return
	 */
	List<E> findBy(String[] attr, Object[] value, String[] nullProperties,
			String[] notNullProperties);

	List<E> findByOrdered(String[] attr, Object[] value,
			String[] nullProperties, String[] notNullProperties, String order,
			boolean ascendant);

	/**
	 * Charge tous les objets manages par ce DAO tout en les triant
	 * 
	 * @return La List d'objet
	 */
	List<E> findAllOrdered(String param, boolean ascendant);

	List<E> findBy(String attr, Object value, int firstResult, int nbMax);

	List<E> findBy(String[] attr, Object[] value, int firstResult, int nbMax);

	List<E> findByOrdered(String attr, Object value, String order,
			boolean ascendant, int firstResult, int nbMax);

	List<E> findByOrdered(String[] attr, Object[] value, String order,
			boolean ascendant, int firstResult, int nbMax);

	E findUniqueResultBy(String attr, Object value);

	E findUniqueResultBy(String[] attr, Object[] value);

	E merge(E e);

	void merge(List<E> elements);

	void evict(E e);

	void evict(List<E> elements);

	void evictAll();

	void flush();

	int getElementCount();

}
